package avicit.bdp.dgs.metadata.rest;

import avicit.bdp.common.dto.approval.ApprovalDTO;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.dgs.metadata.vo.MetadataMessage;
import avicit.bdp.common.service.dto.BdpColumnDTO;
import avicit.bdp.common.service.dto.BdpTableHistoryDTO;
import avicit.bdp.common.service.dto.ColumnPartitionedDTO;
import avicit.bdp.dgs.metadata.dto.MetadataBusinessUpdateDto;
import avicit.bdp.dgs.metadata.dto.MetadataModelAttributeDTO;
import avicit.bdp.dgs.metadata.handler.DbmsStorageHandler;
import avicit.bdp.dgs.metadata.service.MetadataTableColumnPartitionService;
import avicit.bdp.dgs.metadata.service.MetadataTableColumnService;
import avicit.bdp.dgs.metadata.service.MetadataTableHistoryService;
import avicit.bdp.dgs.metadata.service.MetadataTableService;
import avicit.bdp.dgs.metadata.vo.MetadataTableColumnVo;
import avicit.bdp.dgs.metadata.vo.MetadataTableVo;
import avicit.bdp.dgs.metadata.vo.TableVersionCompareResponseVo;
import avicit.platform6.core.rest.msg.QueryRespBean;
import avicit.platform6.core.rest.msg.ResponseMsg;
import com.github.pagehelper.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author mayi
 */
@RestController
@Api(tags = "元数据管理")
@RequestMapping("/api/bdp/dgs/dataAsset/tableMeta")
public class MetadataTableController {

  @Resource private MetadataTableService metadataTableService;
  @Resource private MetadataTableHistoryService metadataTableHistoryService;
  @Resource private MetadataTableColumnService metadataTableColumnService;
  @Resource private MetadataTableColumnPartitionService metadataTableColumnPartitionService;

  @Resource private DbmsStorageHandler dbmsStorageHandler;

  @ApiOperation(value = "分页查询")
  @ApiImplicitParams({
    @ApiImplicitParam(
        value = "数据源类型",
        name = "datasourceType",
        dataType = "String",
        paramType = "query"),
    @ApiImplicitParam(
        value = "数据源",
        name = "dataSourceId",
        dataType = "String",
        paramType = "query"),
    @ApiImplicitParam(value = "空间ID", name = "projectId", dataType = "String", paramType = "query"),
    @ApiImplicitParam(
        value = "数据目录ID",
        name = "catalogId",
        dataType = "String",
        paramType = "query"),
    @ApiImplicitParam(value = "查询关键词", name = "keyWords", dataType = "String", paramType = "query"),
    @ApiImplicitParam(
        value = "是否基于基线版本",
        name = "fromBaseVersion",
        dataType = "Int",
        paramType = "query"),
    @ApiImplicitParam(value = "当前页", name = "pageNo", dataType = "Int", paramType = "query"),
    @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int", paramType = "query")
  })
  @GetMapping
  public ResponseMsg<QueryRespBean<MetadataTableVo>> getPageList(
      @RequestParam(required = false) String datasourceType,
      @RequestParam(required = false) String dataSourceId,
      @RequestParam(required = false) String projectId,
      @RequestParam(required = false) String catalogId,
      @RequestParam(required = false) String keyWords,
      @RequestParam(required = false) Integer status,
      @RequestParam(required = false) Integer fromBaseVersion,
      @RequestParam(defaultValue = "1") Integer pageNo,
      @RequestParam(defaultValue = "10") Integer pageSize)
      throws Exception {

    ResponseMsg<QueryRespBean<MetadataTableVo>> responseMsg = new ResponseMsg<>();
    Page<MetadataTableVo> pageList =
        metadataTableService.getPageList(
            datasourceType,
            dataSourceId,
            projectId,
            catalogId,
            keyWords,
            status,
            fromBaseVersion,
            pageNo,
            pageSize);

    QueryRespBean<MetadataTableVo> queryRespBean = new QueryRespBean<>();
    queryRespBean.setResult(pageList);
    BdpLogUtil.log4Query("元数据管理模块", "元数据管理", queryRespBean);
    responseMsg.setResponseBody(queryRespBean);

    return responseMsg;
  }

  @ApiOperation(value = "批量删除")
  @ApiParam(value = "ID数组", name = "ids", required = true)
  @DeleteMapping
  public ResponseMsg<Boolean> batchDelete(@RequestBody List<String> ids) {
    ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.batchDelete(ids));
    return responseMsg;
  }

  @ApiOperation(value = "通过ID查询")
  @GetMapping("/{id}")
  public ResponseMsg<MetadataTableVo> queryById(@PathVariable String id) {
    ResponseMsg<MetadataTableVo> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.queryById(id));
    return responseMsg;
  }

  @ApiOperation(value = "通过条件查询元数据")
  @GetMapping("/queryByDataSourceIdAndName")
  public ResponseMsg<MetadataTableVo> queryByDataSourceIdAndName(
      @RequestParam("metadataCollectTaskId") String metadataCollectTaskId,
      @RequestParam("datasourceId") String datasourceId,
      @RequestParam("name") String name) {
    ResponseMsg<MetadataTableVo> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(
        metadataTableService.queryByDataSourceIdAndName(metadataCollectTaskId, datasourceId, name));
    return responseMsg;
  }

  @ApiOperation(value = "数据预览")
  @GetMapping("/{id}/preview")
  @ApiImplicitParams({
    @ApiImplicitParam(value = "id", name = "id", dataType = "String", paramType = "path"),
    @ApiImplicitParam(value = "当前页", name = "currentPage", dataType = "Int", paramType = "query"),
    @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int", paramType = "query")
  })
  public ResponseMsg<Map<String, Object>> preview(
      @PathVariable String id,
      @RequestParam(defaultValue = "1") Integer currentPage,
      @RequestParam(defaultValue = "50") Integer pageSize) {
    ResponseMsg<Map<String, Object>> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.preview(id, currentPage, pageSize));
    return responseMsg;
  }

  @ApiOperation(value = "分页查询列数据")
  @ApiImplicitParams({
    @ApiImplicitParam(
        value = "表ID",
        name = "tableId",
        dataType = "String",
        paramType = "query",
        required = true),
    @ApiImplicitParam(value = "查询关键词", name = "keyWords", dataType = "String", paramType = "query"),
    @ApiImplicitParam(value = "当前页", name = "pageNo", dataType = "Int", paramType = "query"),
    @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int", paramType = "query")
  })
  @GetMapping(value = "/column/page")
  public ResponseMsg<QueryRespBean<BdpColumnDTO>> getColumnPageList(
      @RequestParam String tableId,
      @RequestParam(required = false) String keyWords,
      @RequestParam(defaultValue = "1") Integer pageNo,
      @RequestParam(defaultValue = "10") Integer pageSize)
      throws Exception {

    ResponseMsg<QueryRespBean<BdpColumnDTO>> responseMsg = new ResponseMsg<>();
    Page<BdpColumnDTO> pageList =
        metadataTableColumnService.selectPageList(tableId, keyWords, pageNo, pageSize);
    QueryRespBean<BdpColumnDTO> queryRespBean = new QueryRespBean<>();
    queryRespBean.setResult(pageList);
    responseMsg.setResponseBody(queryRespBean);
    return responseMsg;
  }

  @ApiOperation(value = "查询列数据")
  @ApiImplicitParams({
    @ApiImplicitParam(value = "表ID", name = "tableId", dataType = "String", paramType = "query"),
    @ApiImplicitParam(
        value = "标准ID",
        name = "standardId",
        dataType = "String",
        paramType = "query"),
    @ApiImplicitParam(value = "查询关键词", name = "keyWords", dataType = "String", paramType = "query")
  })
  @GetMapping(value = "/column/list")
  public ResponseMsg<List<MetadataTableColumnVo>> getColumnList(
      @RequestParam(required = false) String tableId,
      @RequestParam(required = false) String standardId,
      @RequestParam(required = false) String keyWords) {

    ResponseMsg<List<MetadataTableColumnVo>> responseMsg = new ResponseMsg<>();
    List<MetadataTableColumnVo> list =
        metadataTableColumnService.selectList(tableId, standardId, keyWords);
    responseMsg.setResponseBody(list);
    return responseMsg;
  }

  @ApiOperation(value = "分页查询分区数据")
  @ApiImplicitParams({
    @ApiImplicitParam(
        value = "表ID",
        name = "tableId",
        dataType = "String",
        paramType = "query",
        required = true),
    @ApiImplicitParam(value = "查询关键词", name = "keyWords", dataType = "String", paramType = "query"),
    @ApiImplicitParam(value = "当前页", name = "pageNo", dataType = "Int", paramType = "query"),
    @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int", paramType = "query")
  })
  @GetMapping(value = "/partitionColumn/page")
  public ResponseMsg<QueryRespBean<ColumnPartitionedDTO>> getPartitionColumnPageList(
      @RequestParam String tableId,
      @RequestParam(required = false) String keyWords,
      @RequestParam(defaultValue = "1") Integer pageNo,
      @RequestParam(defaultValue = "10") Integer pageSize)
      throws Exception {

    ResponseMsg<QueryRespBean<ColumnPartitionedDTO>> responseMsg = new ResponseMsg<>();
    Page<ColumnPartitionedDTO> pageList =
        metadataTableColumnPartitionService.selectPageList(tableId, keyWords, pageNo, pageSize);
    QueryRespBean<ColumnPartitionedDTO> queryRespBean = new QueryRespBean<>();
    queryRespBean.setResult(pageList);
    responseMsg.setResponseBody(queryRespBean);
    return responseMsg;
  }

  @ApiOperation(value = "上架")
  @ApiParam(value = "ID数组", name = "ids", required = true)
  @PostMapping("/online")
  public ResponseMsg<Boolean> online(@RequestBody List<String> ids) {
    ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.publish(ids));
    return responseMsg;
  }

  @ApiOperation(value = "下架")
  @ApiParam(value = "ID数组", name = "ids", required = true)
  @PostMapping("/offline")
  public ResponseMsg<Boolean> offline(@RequestBody List<String> ids) {
    ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.offline(ids));
    return responseMsg;
  }

  @ApiOperation(value = "撤回")
  @ApiParam(value = "逗号分隔的id串", name = "ids", required = true)
  @PostMapping("/revoke")
  public ResponseMsg<Boolean> revoke(@RequestBody List<String> ids) {
    ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.revoke(ids));
    return responseMsg;
  }

  /** 接收审批中心通知 */
  @PostMapping("/receiveMsg")
  @ApiOperation(value = "接收审批中心通知")
  public ResponseMsg<Boolean> receiveMsgFromApprovalCenter(
      @RequestBody List<ApprovalDTO> approvalList) {

    ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(
        this.metadataTableService.receiveMsgFromApprovalCenter(approvalList));
    return responseMsg;
  }

  @ApiOperation(value = "通过ID查询业务属性")
  @GetMapping("/{id}/business")
  public ResponseMsg<List<MetadataModelAttributeDTO>> getBusinessList(@PathVariable String id) {
    ResponseMsg<List<MetadataModelAttributeDTO>> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.getBusinessList(id));
    return responseMsg;
  }

  @ApiOperation(value = "通过ID查询技术属性")
  @GetMapping("/{id}/technology")
  public ResponseMsg<List<MetadataModelAttributeDTO>> getTechnologyList(@PathVariable String id) {
    ResponseMsg<List<MetadataModelAttributeDTO>> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.getTechnologyList(id));
    return responseMsg;
  }

  @ApiOperation(value = "通过ID批量更新业务属性")
  @PostMapping("/business/update")
  public ResponseMsg<Boolean> batchUpdateBusinessList(
      @RequestBody MetadataBusinessUpdateDto updateDto) {
    ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableService.batchUpdateBusinessList(updateDto));
    return responseMsg;
  }

  @ApiOperation(value = "分页查询版本")
  @ApiImplicitParams({
    @ApiImplicitParam(value = "元数据表ID", name = "tableId", dataType = "String", paramType = "query"),
    @ApiImplicitParam(value = "当前页", name = "pageNo", dataType = "Int", paramType = "query"),
    @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int", paramType = "query")
  })
  @GetMapping("/versions")
  public ResponseMsg<QueryRespBean<BdpTableHistoryDTO>> getVersionPage(
      @RequestParam String tableId,
      @RequestParam(defaultValue = "1") Integer pageNo,
      @RequestParam(defaultValue = "10") Integer pageSize) {

    ResponseMsg<QueryRespBean<BdpTableHistoryDTO>> responseMsg = new ResponseMsg<>();
    QueryRespBean<BdpTableHistoryDTO> queryRespBean =
        metadataTableHistoryService.getVersionPage(tableId, pageNo, pageSize);
    responseMsg.setResponseBody(queryRespBean);
    return responseMsg;
  }

  @ApiOperation(value = "通过ID查询历史记录")
  @GetMapping("/history/{id}")
  public ResponseMsg<MetadataTableVo> queryHistoryByIdAndVersion(@PathVariable String id) {
    ResponseMsg<MetadataTableVo> responseMsg = new ResponseMsg<>();
    responseMsg.setResponseBody(metadataTableHistoryService.queryHistoryById(id));
    return responseMsg;
  }

  @ApiImplicitParams({
    @ApiImplicitParam(
        value = "当前版本",
        name = "sourceVersionId",
        dataType = "String",
        paramType = "query",
        required = true),
    @ApiImplicitParam(
        value = "对比版本",
        name = "targetVersionId",
        dataType = "String",
        paramType = "query",
        required = true)
  })
  @GetMapping("/compare")
  @ApiOperation(value = "版本对比")
  public ResponseMsg<TableVersionCompareResponseVo> compare(
      @RequestParam String sourceVersionId, @RequestParam String targetVersionId) {

    if (StringUtils.isAnyEmpty(sourceVersionId, targetVersionId)) {
      throw new IllegalArgumentException("请检查参数");
    }
    ResponseMsg<TableVersionCompareResponseVo> responseMsg = new ResponseMsg<>();
    TableVersionCompareResponseVo responseDTO =
        metadataTableHistoryService.compare(sourceVersionId, targetVersionId);
    responseMsg.setResponseBody(responseDTO);
    return responseMsg;
  }

  @ApiImplicitParams({
    @ApiImplicitParam(
        value = "元数据ID",
        name = "metadataId",
        dataType = "String",
        paramType = "query",
        required = true),
    @ApiImplicitParam(
        value = "当前版本",
        name = "sourceVersion",
        dataType = "String",
        paramType = "query",
        required = true),
    @ApiImplicitParam(
        value = "对比版本",
        name = "targetVersion",
        dataType = "String",
        paramType = "query")
  })
  @GetMapping("/compareWithVersion")
  @ApiOperation(value = "通过版本号进行版本对比")
  public ResponseMsg<TableVersionCompareResponseVo> compareWithVersion(
      @RequestParam String metadataId,
      @RequestParam String sourceVersion,
      @RequestParam(required = false) String targetVersion) {

    if (StringUtils.isAnyEmpty(metadataId, sourceVersion)) {
      throw new IllegalArgumentException("请检查参数");
    }
    ResponseMsg<TableVersionCompareResponseVo> responseMsg = new ResponseMsg<>();
    TableVersionCompareResponseVo responseDTO =
        metadataTableHistoryService.compareWithVersion(metadataId, sourceVersion, targetVersion);
    responseMsg.setResponseBody(responseDTO);
    return responseMsg;
  }

  @ApiOperation(value = "处理元数据消息体")
  @PostMapping("/handleMetadataMessage")
  public ResponseMsg<Boolean> handleMetadataMessage(@RequestBody MetadataMessage metadataMessage) {
    ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
    dbmsStorageHandler.handle(metadataMessage);
    responseMsg.setResponseBody(true);
    return responseMsg;
  }
}
